// 微信公众号
const createConfig = require('uni-config-center');
/**
 * 获取url
 * @param {*} mpConfig
 * @returns
 */
function getAuthUrl(mpConfig, $dx) {
	let url = $dx.request.post('url');
	let state = 'dxadmin';
	if (!url) {
		$dx.error('未获取到 url');
	}
	if (url.includes('#')) {
		let urls = url.split('#');
		url = urls[0];
		state = state + '__' + urls[1];
	}
	url = encodeURIComponent(url);
	return `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${mpConfig.appid}&redirect_uri=${url}&response_type=code&scope=${mpConfig.scope}&state=${state}#wechat_redirect`;
}
/**
 * 授权信息
 * @param {*} mpConfig
 * @param {*} code
 * @param {*} state
 * @returns
 */
async function getAuthInfo(mpConfig, code, $dx) {
	// https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
	const url = `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${mpConfig.appid}&secret=${mpConfig.appsecret}&code=${code}&grant_type=authorization_code`;
	const http = new $dx.Curl();
	const res = await http.get(url);
	if (res.errcode) {
		$dx.error(res.errmsg);
	}
	const dcloud_appid = $dx.request.appId;
	let user;
	if (res.unionid) {
		user = await $dx.service.user.where('wx_unionid', res.unionid).find();
		// 判断和更新用户信息
		// 其他凭他的openid 更新到当前用户
		if (user && (!user.wx_openid || user.wx_openid.h5 !== res.openid)) {
			await $dx.service.user.save({
				_id: user._id,
				wx_openid: {
					h5: res.openid,
				},
				third_party: {
					h5_weixin: {
						access_token: res.access_token,
						access_token_expired: res.expires_in,
						refresh_token: res.refresh_token,
					},
				},
			});
		}
	}
	if (!user) {
		user = await $dx.service.user.where('wx_openid.h5', res.openid).find();
	}
	// 找到了
	if (user) {
		// 用户已禁用
		if (user.status !== 0) {
			$dx.error('用户已禁用');
		}
		// 判断是否有应用权限
		if (user.dcloud_appid.length && !user.dcloud_appid.includes(dcloud_appid)) {
			await $dx.service.logs.addLoginLog(user._id, user.username, 'login', 0, user.mobile, user.email);
			$dx.error('账号没有应用权限');
		}
		// 登录
		return await $dx.service.user.loginByUser(user);
	}
	// 没找到
	user = {
		wx_openid: {
			h5: res.openid,
		},
		third_party: {
			h5_weixin: {
				access_token: res.access_token,
				access_token_expired: res.expires_in,
				refresh_token: res.refresh_token,
			},
		},
	};
	if (res.unionid) {
		user.wx_unionid = res.unionid;
	}
	// 获取用户信息
	if (res.scope === 'snsapi_userinfo') {
		// https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
		const url = `https://api.weixin.qq.com/sns/userinfo?access_token=${res.access_token}&openid=${res.openid}&lang=zh_CN`;
		const result = await http.get(url);
		if (!result.errcode) {
			user.nickname = result.nickname;
			user.avatar = result.headimgurl;
			user.gender = result.sex;
			user.wx_unionid = result.unionid;
		}
	} else {
		user.nickname = '微信用户' + res.openid.substr(0, 4) + '****' + res.openid.substr(-4);
	}
	const time = Date.now();
	const ip = $dx.request.ip;
	user.username = res.openid;
	user.role = [];
	user.register_date = time;
	user.register_ip = ip;
	user.last_login_ip = ip;
	user.last_login_date = time;
	user.status = 0;
	user.dcloud_appid = [dcloud_appid];
	user.mobile = '';
	user.email = '';
	user.money = 0;
	user.score = 0;
	// 注册
	let uid = await $dx.service.user.insert(user);
	user._id = uid;
	return await $dx.service.user.loginByUser(user);
}

module.exports = {
	// 登陆
	async login() {
		const uniIdConfig = createConfig({
			pluginId: 'uni-id', // 插件id
			// defaultConfig: {},
			customMerge: function (defaultConfig, userConfig) {
				return Object.assign(defaultConfig, userConfig);
			},
		});
		const config = uniIdConfig.config('wechat.oauth');
		const dCloudAppid = this.$dx.request.appId;
		if (!dCloudAppid) {
			this.$dx.error('未获取到 dCloud Appid');
		}
		if (!config || !config[dCloudAppid] || !config[dCloudAppid].appid) {
			this.$dx.error('未配置小程序 Appid');
		}
		const mpConfig = config[dCloudAppid];
		const code = this.$dx.request.post('code');
		const state = this.$dx.request.post('state');
		if (!code && !state) {
			return getAuthUrl(mpConfig, this.$dx);
		}
		if (state !== 'dxadmin') {
			this.$dx.error('state 不正确');
		}
		if (!code) {
			this.$dx.error('未获取到 code');
		}
		return await getAuthInfo(mpConfig, code, this.$dx);
	},
};
